﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using System.Threading.Tasks;

namespace Ymatou.ServiceCenter
{
    public static class ListExtensions
    {
        public static void AddList<T>(this IList<T> list, IList<T> items)
        {
            if (list == null || items == null)
                return;
            foreach (T item in items)
            {
                if (item == null)
                    continue;
                list.Add(item);
            }
        }

        public static IDictionary<string, string> GetServiceClientRequestHeader(this HttpRequestMessage httpRequestMessage)
        {
            if (httpRequestMessage == null)
                return null;

            string requestId = httpRequestMessage.Headers.Contains("RequestId")? httpRequestMessage.Headers.GetValues("RequestId").FirstOrDefault():null;
            string requestIndex = httpRequestMessage.Headers.Contains("RequestIndex")?httpRequestMessage.Headers.GetValues("RequestIndex").FirstOrDefault():null;
            string clientIp = httpRequestMessage.GetClientIp();
            string serverIpLink = httpRequestMessage.GetServerIpLink();
            IDictionary<string, string> headers = new Dictionary<string, string>();
            if(!string.IsNullOrWhiteSpace(requestId))
                headers.Add("RequestId", requestId);
            if (!string.IsNullOrWhiteSpace(requestIndex))
                headers.Add("RequestIndex", requestIndex);
            if (!string.IsNullOrWhiteSpace(clientIp))
                headers.Add("ClientIp",clientIp);
            if (!string.IsNullOrWhiteSpace(serverIpLink))
                headers.Add("ServerIpLink", serverIpLink);
            return headers;
        }

        public static string GetName(this PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
                return null;
            JsonPropertyAttribute attribute = Utils.GetFirstAttribute<JsonPropertyAttribute>(propertyInfo, true);
            if (attribute == null)
                return propertyInfo.Name;
            return attribute.PropertyName;
        }

        public static void TryEach<T>(this IEnumerable<T> instance, Action<T> action, bool parallel = false, bool exceptionBreak = false, Action<Exception> handle = null)
        {
            if (instance == null) return;
            if (parallel)
            {
                Parallel.ForEach(instance, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, e =>
                {
                    try { action(e); }
                    catch (Exception ex)
                    {
                        if (handle != null) handle(ex);
                        if (exceptionBreak) throw new AggregateException(ex);
                    }
                });
            }
            else
            {
                foreach (T item in instance)
                {
                    try
                    {
                        action(item);
                    }
                    catch (Exception ex)
                    {
                        if (handle != null) handle(ex);
                        if (exceptionBreak) throw;
                    }
                }
            }
        }
    }
}
